package coba.util;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import com.liferay.portal.kernel.util.StringUtil;

public class SQLSolicitudes {

	public static List<SolicitudId> findByMap(Map<String, String> map, int begin, int end) throws SQLException, ClassNotFoundException, IOException, ParseException {
		Connection con = null;

		try {
			con = ConnectionFactory.getConnection();
		
			return findByMap(con, map, begin, end);
		}
		finally {
			if (con != null)
				con.close();
		}

	}

	public static int countByMap(Map<String, String> map) throws SQLException, ClassNotFoundException, IOException, ParseException {
		Connection con = null;

		try {
			con = ConnectionFactory.getConnection();
		
			return countByMap(con, map);
		}
		finally {
			if (con != null)
				con.close();
		}

	}

	public static List<SolicitudId> findByMap(Connection con, Map<String, String> map, int begin, int end) throws SQLException, ParseException {

		PreparedStatement stmt = con.prepareStatement(createSql(map, false, begin, end));

		addCriterios(stmt, map);

		ResultSet rs = stmt.executeQuery();

		List<SolicitudId> list = new LinkedList<SolicitudId>();

		while (rs.next()) {
			list.add(new SolicitudId(rs.getLong("s.id_")));
		}

		rs.close();
		stmt.close();

		return list;

	}

	public static int countByMap(Connection con, Map<String, String> map) throws SQLException, ParseException {

		PreparedStatement stmt = con.prepareStatement(createSql(map, true, 0, 0));

		addCriterios(stmt, map);

		ResultSet rs = stmt.executeQuery();

		rs.next();

		int retval = rs.getInt(1);

		rs.close();
		stmt.close();

		return retval;

	}

	private static String createSql(Map<String, String> map, boolean count, int begin, int end) {

		StringBuilder sb = new StringBuilder();
		
		if (count)
			sb.append(" select count(distinct s.id_) ");
		else
			sb.append(" select distinct s.id_ ");
		
		sb.append(" from COBA_Solicitudes s ").
				append(" inner join COBA_Contactos c on c.id_ = s.contactoId ").
				append(" inner join COBA_Instituciones i on i.id_ = c.institucionId ").
				append(" inner join COBA_Itinerarios it on it.id_ = s.itinerarioId ").
				append(" inner join COBA_ItinerarioRecorridos ir on ir.itinerarioId = it.id_ ").
				append(" left join COBA_SolicitudGuia sg on sg.solicitudId = s.id_ ").
				append(" where s.fechaBaja is null ");

		if (map.get("codigo") != null && !map.get("codigo").trim().equals("")) {
			String[] arrCodigo = map.get("codigo").split("-");

			if (arrCodigo.length > 3) {
				sb.append(" and false ");
			}
			else if (arrCodigo.length == 3) {
				sb.append(" and it.modalidad like ? ");
				sb.append(" and SUBSTRING(i.localidad, 1, 3) like ? ");
				sb.append(" and CONCAT(SUBSTRING('0000', 1, 7 - LENGTH(s.numero)), s.numero) like ? ");
			}
			else if (arrCodigo.length == 2) {
				sb.append(" and ( ");
				sb.append(" (it.modalidad like ? and SUBSTRING(i.localidad, 1, 3) like ?) ");
				sb.append(" or ");
				sb.append(" (SUBSTRING(i.localidad, 1, 3) like ? and CONCAT(SUBSTRING('0000', 1, 7 - LENGTH(s.numero)), s.numero) like ?) ");
				sb.append(" ) ");
			}
			else if (arrCodigo.length == 1) {
				sb.append(" and ( ");
				sb.append(" it.modalidad like ? ");
				sb.append(" or ");
				sb.append(" SUBSTRING(i.localidad, 1, 3) like ? ");
				sb.append(" or ");
				sb.append(" CONCAT(SUBSTRING('0000', 1, 7 - LENGTH(s.numero)), s.numero) like ? ");
				sb.append(" ) ");				
			}
		}

		if (map.get("modalidad") != null && !map.get("modalidad").trim().equals("")) {
			sb.append(" and it.modalidad = ? ");
		}

		if (map.get("itinerarioId") != null && !map.get("itinerarioId").trim().equals("")) {
			sb.append(" and s.itinerarioId = ? ");
		}

		if (map.get("localidad") != null && !map.get("localidad").trim().equals("")) {
			sb.append(" and i.localidad like ? ");
		}

		if (map.get("estado") != null && !map.get("estado").trim().equals("")) {
			if ("1".equals(map.get("estado").trim()))
				sb.append(" and s.fechaConfirmacionItinerario is null and s.fechaItinerario >= now() ");
			else if ("2".equals(map.get("estado").trim()))
				sb.append(" and s.fechaConfirmacionItinerario is not null and s.fechaItinerario >= now() ");
			else if ("3".equals(map.get("estado").trim()))
				sb.append(" and s.fechaItinerario < now() ");
		}

		if (map.get("recorridoId") != null && !map.get("recorridoId").trim().equals("")) {
			sb.append(" and ir.recorridoId = ? ");
		}

		if (map.get("arrGuiaId") != null && !map.get("arrGuiaId").trim().equals("")) {
			sb.append(" and sg.guiaId in (");

			String[] arrGuiaId = StringUtil.split(map.get("arrGuiaId"), ",");
			for (int i = 0; i < arrGuiaId.length; i++) {
				if (i > 0)
					sb.append(",");
				sb.append("?");
			}

			sb.append(") ");
		}

		if (map.get("institucion") != null && !map.get("institucion").trim().equals("")) {
			sb.append(" and i.nombre like ? ");
		}

		if (map.get("fechaDesde") != null && !map.get("fechaDesde").trim().equals("")) {
			sb.append(" and s.fechaItinerario >= ? ");
		}

		if (map.get("fechaHasta") != null && !map.get("fechaHasta").trim().equals("")) {
			sb.append(" and s.fechaItinerario <= ? ");
		}

		if (!count) {
			sb.append(" order by s.fechaItinerario ");
			sb.append(" limit ").append(begin).append(",").append(end - begin);
		}
		
		return sb.toString();

	}

	private static PreparedStatement addCriterios(PreparedStatement stmt, Map<String, String> map) throws SQLException, ParseException {

		int nCriterio = 1;

		if (map.get("codigo") != null && !map.get("codigo").trim().equals("")) {
			String[] arrCodigo = map.get("codigo").split("-");

			if (arrCodigo.length == 3) {
				stmt.setString(nCriterio++, "%" + arrCodigo[0]);
				stmt.setString(nCriterio++, arrCodigo[1]);
				stmt.setString(nCriterio++, arrCodigo[2] + "%");
			}
			else if (arrCodigo.length == 2) {
				stmt.setString(nCriterio++, "%" + arrCodigo[0]);
				stmt.setString(nCriterio++, arrCodigo[1] + "%");
				stmt.setString(nCriterio++, "%" + arrCodigo[0]);
				stmt.setString(nCriterio++, arrCodigo[1] + "%");
			}
			else if (arrCodigo.length == 1) {
				stmt.setString(nCriterio++, "%" + arrCodigo[0] + "%");
				stmt.setString(nCriterio++, "%" + arrCodigo[0] + "%");
				stmt.setString(nCriterio++, "%" + arrCodigo[0] + "%");
			}
		}

		if (map.get("modalidad") != null && !map.get("modalidad").trim().equals("")) {
			stmt.setString(nCriterio++, map.get("modalidad").trim());
		}

		if (map.get("itinerarioId") != null && !map.get("itinerarioId").trim().equals("")) {
			stmt.setLong(nCriterio++, Long.valueOf(map.get("itinerarioId").trim()));
		}

		if (map.get("localidad") != null && !map.get("localidad").trim().equals("")) {
			stmt.setString(nCriterio++, "%" + map.get("localidad").trim() + "%");
		}

		if (map.get("recorridoId") != null && !map.get("recorridoId").trim().equals("")) {
			stmt.setLong(nCriterio++, Long.valueOf(map.get("recorridoId").trim()));
		}

		if (map.get("institucion") != null && !map.get("institucion").trim().equals("")) {
			stmt.setString(nCriterio++, "%" + map.get("institucion").trim() + "%");
		}

		if (map.get("arrGuiaId") != null && !map.get("arrGuiaId").trim().equals("")) {
			String[] arrGuiaId = StringUtil.split(map.get("arrGuiaId"), ",");

			for (String guiaId : arrGuiaId) {
				stmt.setLong(nCriterio++, Long.valueOf(guiaId));
			}
		}

		if (map.get("fechaDesde") != null && !map.get("fechaDesde").trim().equals("")) {
			Date fechaDesde = new SimpleDateFormat("yyyy-MM-dd").parse(map.get("fechaDesde"));
			stmt.setObject(nCriterio++, fechaDesde);
		}

		if (map.get("fechaHasta") != null && !map.get("fechaHasta").trim().equals("")) {
			Date fechaHasta = new SimpleDateFormat("yyyy-MM-dd").parse(map.get("fechaHasta"));
			stmt.setObject(nCriterio++, fechaHasta);
		}

		return stmt;

	}

}
